<?php
error_reporting(E_WARNING | E_PARSE);
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
//declare(ticks=1);

/**
 * 聊天主逻辑
 * 主要是处理 onMessage onClose 
 */
use \GatewayWorker\Lib\Gateway;
use Chat\Chat;
class Events
{
   /**
    * 有消息时
    * @param int $client_id
    * @param mixed $message
    */
   public static function onMessage($client_id, $message)
   {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
        
        // 客户端传递的是json数据
        $message_data = json_decode($message, true);
        if(!$message_data)
        {
            return ;
        }
        //实例化聊天类
        $chat = new Chat();

        
        // 根据类型执行不同的业务
        switch($message_data['type'])
        {
            // 客户端回应服务端的心跳
            case 'pong':
                return;
            // 客户端登录 message格式: {type:logi, name:xx, room_id:1} ，添加到客户端，广播给所有客户端xx进入聊天室
            case 'login':
                
                // 把房间号昵称放到session中
                $client_name = htmlspecialchars($message_data['client_name']);
                $chat_type = $message_data['chat_type'];
                $user_id = $message_data['user_id'];
                $friend_id = $message_data['friend_id'];
                $group_id = $message_data['group_id'];
                //获取房间ID
                $room_id = $chat->get_room_id($user_id,$friend_id,$group_id,$chat_type);

                // 判断是否有房间号
                if(!isset($room_id))
                {
                    throw new \Exception("\$room_id not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                }
                

                $_SESSION['chat_type'] = $chat_type;
                $_SESSION['room_id'] = $room_id;
                $_SESSION['client_name'] = $client_name;
                $_SESSION['user_id'] = $user_id;
                $_SESSION['friend_id'] = $friend_id;
                $_SESSION['group_id'] = $group_id;
              
               //修改聊天消息状态（有无未读消息）
                $clients_list = Gateway::getClientSessionsByGroup($room_id);
                   
                /*foreach($clients_list as $tmp_client_id=>$item)
                {
                    $clients_list[$tmp_client_id] = $item['client_name'];
                }
                $clients_list[$client_id] = $client_name;*/

                // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx} 
                $new_message = array('type'=>$message_data['type'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'room_id'=>$room_id, 'time'=>date('Y-m-d H:i:s'));
                //Gateway::sendToGroup($room_id, json_encode($new_message));
                Gateway::joinGroup($client_id, $room_id);
               
                // 给当前用户发送用户列表 
                //$new_message['client_list'] = $clients_list;
                Gateway::sendToCurrentClient(json_encode($new_message));

                return;
                
            // 客户端发言 message: {type:say, to_client_id:xx, content:xx}
            case 'say':

                // 非法请求
                if(!isset($_SESSION['room_id']))
                {
                    throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
                }
                $room_id = $_SESSION['room_id'];
                $client_name = $_SESSION['client_name'];
                $chat_type = $_SESSION['chat_type'];
                $user_id = $_SESSION['user_id'];

                $chat_data = array();
                if($chat_type == "group"){
                    $group_id = $_SESSION['group_id'];
                    $chat_data["user_id"] = $user_id;
                }else{                    
                    $friend_id = $_SESSION['friend_id'];
                    $chat_data["friend_id"] = $friend_id;
                    $chat_data["user_id"] = $user_id;
                }
                $chat_data["room_id"] = $room_id;
                $chat_data["add_time"] = time();
                $chat_data["content"] = $message_data['content'];

                $chat ->add_record($chat_data);

                //把自己添加到对方的聊天列表
                $clients_list = Gateway::getClientSessionsByGroup($room_id);
                if($chat_type == "friend"){
                    $chat->add_friend($friend_id, $user_id, 1);
                    $chat->add_friend($user_id, $friend_id, 0);
                }else if($chat_type == "group"){
                    $group = $chat->get_group_info($group_id);
                    if($group){
                        $group_users = array_filter(explode(",",$group["users"]));
                        if($group_users){
                            foreach($group_users as $row){
                                if($row == $user_id){
                                    $chat->add_group($row, $group_id, 0);
                                }else{
                                    $chat->add_group($row, $group_id, 1);
                                }
                            }                            
                        }                        
                    }
                }


                
                // 私聊
                /*if($message_data['to_client_id'] != 'all')
                {
                    $new_message = array(
                        'type'=>'say',
                        'from_client_id'=>$client_id, 
                        'from_client_name' =>$client_name,
                        'to_client_id'=>$message_data['to_client_id'],
                        //'content'=>"<b>对你说: </b>".nl2br(htmlspecialchars($message_data['content'])),
                        'content'=>nl2br(htmlspecialchars($message_data['content'])),
                        'time'=>date('Y-m-d H:i:s'),
                    );
                    Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
                    //$new_message['content'] = "<b>你对".htmlspecialchars($message_data['to_client_name'])."说: </b>".nl2br(htmlspecialchars($message_data['content']));
                    $new_message['content'] = nl2br(htmlspecialchars($message_data['content']));
                    return Gateway::sendToCurrentClient(json_encode($new_message));
                }*/


                $new_message = array(
                    'type'=>'say', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>'all',
                    'chat_type'=>$chat_type,
                    'room_id'=>$room_id,
                    'content'=>$message_data['content'],
                    'time'=>date('Y-m-d H:i:s')
                );
                if($chat_type == "group"){
                    $new_message["user_id"] = $user_id;
                    $new_message["group_id"] = $group_id;                 
                }else{                    
                    $new_message["friend_id"] = $friend_id;
                    $new_message["user_id"] = $user_id;
                }
                return Gateway::sendToGroup($room_id ,json_encode($new_message));

            case 'upload':
                $content =$message_data['content'];
                if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $result)){
                    $type = $result[2];
                    $new_file = "upload/chat/".date('Ymd',time())."/";
                    if(!file_exists($new_file))
                    {
                        mkdir($new_file, 0777, true);
                    }
                    $new_file = $new_file.time().".{$type}";
                    $img_url = array();
                    if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $content)))){
                        $img_url =$new_file;
                    }
                }
                $new_message = array(
                    'type'=>'history', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>$client_id,
                    'image_url'=>$img_url
                ); 
                Gateway::sendToCurrentClient(json_encode($new_message));
                return;
            case 'history':
                $page = $message_data['page'];
                $list_rows = $message_data['list_rows'];
                $room_id = $_SESSION["room_id"];
                $user_id = $_SESSION["user_id"];
                $chat_type = $_SESSION["chat_type"];
                if($chat_type == "group"){
                    $group_id = $_SESSION["group_id"];
                    $chat->add_group($user_id, $group_id, 0);                    
                }else{
                    $friend_id = $_SESSION["friend_id"];                    
                    $chat->add_friend($user_id, $friend_id, 0);
                }
                
                $key = "chat_".$room_id;
                $rt = $chat->get_records($key,$page,$list_rows);

                //如果是客服，添加自动回复
                if($chat_type == "friend" && in_array($friend_id, array(3982))){
                    $hello = array(
                        "user_id"=>$friend_id,
                        "friend_id"=>$user_id,
                        "add_time"=>time(),
                        "content"=>"亲，欢迎关注WIFI在线，客服正在接待其他用户，请稍等，会尽快为您服务！（或请添加WiFi在线微信客服~小叶：WiFi946946）"
                    );
                    array_unshift($rt, $hello);
                }

                $new_message = array(
                    'type'=>'history', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>$client_id,
                    'history'=>$rt,
                    'time'=>date('Y-m-d H:i:s')
                );

                Gateway::sendToCurrentClient(json_encode($new_message));
                return;
            case 'user':
                $user_id = $message_data['user_id'];
                
                $rt = $chat -> get_user_info($user_id);

                $new_message = array(
                    'type'=>'user', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>$client_id,
                    'user_info'=>$rt,
                    'time'=>date('Y-m-d H:i:s')
                );
                Gateway::sendToCurrentClient(json_encode($new_message));

                return;
            case 'friend':
                $user_id = $message_data['friend_id'];
                
                $rt = $chat -> get_user_info($user_id);

                $new_message = array(
                    'type'=>'friend', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>$client_id,
                    'user_info'=>$rt,
                    'time'=>date('Y-m-d H:i:s')
                );
                Gateway::sendToCurrentClient(json_encode($new_message));

                return;
            case 'group':
                $group_id = $message_data['group_id'];
                $user_list = array();

                $rt = $chat -> get_group_info($group_id);                
                if($rt){
                    $group_users = array_unique(array_filter(explode(",",$rt["users"])));

                    if($group_users){
                        $user_list = $chat->get_user_list($group_users);                             
                    }                        
                }
                
                $new_message = array(
                    'type'=>'group', 
                    'from_client_id'=>$client_id,
                    'from_client_name' =>$client_name,
                    'to_client_id'=>$client_id,
                    'group_info'=>$rt,
                    'group_users'=>$user_list,
                    'time'=>date('Y-m-d H:i:s')
                );
                Gateway::sendToCurrentClient(json_encode($new_message));

                return;
        }
   }
   
   /**
    * 当客户端断开连接时
    * @param integer $client_id 客户端id
    */
   public static function onClose($client_id)
   {
       // debug
       echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";
       
       // 从房间的客户端列表中删除
       if(isset($_SESSION['room_id']))
       {
           $room_id = $_SESSION['room_id'];
           $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
           Gateway::sendToGroup($room_id, json_encode($new_message));
       }
   }
  
}
